﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using Vision.Common;

namespace Vision.Utilities.DataAnalytics
{
    public class PingdomApiClient
    {
        static readonly DateTime UnixDateTimeStart = new DateTime(1970, 1, 1);
        public const string USCountryISO = "US";
        public const string CanadaCountryISO = "CA"; 

        public PingdomApiClient(string apiUrl = "https://api.pingdom.com", string userName = "webmaster@visioninternet.com", string password = "Vision3100!", string appKey = "sirwk18w28ck2umhdq7rsg5rgub363pr")
        {
            ApiUrl = apiUrl;
            UserName = userName;
            Password = password;
            AppKey = appKey;
        }

        public string ApiUrl { get; set; }

        public string UserName { get; set; }

        public string Password { get; set; }

        public string AppKey { get; set; }

        public static int ToUnixTimestamp(DateTime dateTime)
        {
            return (int)(dateTime.Subtract(UnixDateTimeStart)).TotalSeconds;
        }

        public static DateTime ToDateTime(int unixTimestamp)
        {
            return UnixDateTimeStart.AddSeconds(unixTimestamp);
        }

        private IDictionary<string, string> GetApiHeaders()
        {
            var headers = new Dictionary<string, string>();
            headers.Add("App-Key", AppKey);

            var authInfo = UserName + ":" + Password;
            authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
            headers["Authorization"] = "Basic " + authInfo;

            return headers;
        }

        public List<PingdomCheck> GetAllChecks()
        {
            //var summaryAverageUrl = string.Format("{0}/api/{1}/summary.average/{2}", ApiUrl, "2.0", 1350741);
            var url = string.Format("{0}{1}", ApiUrl, "/api/2.0/checks");
            var response = WebUtils.DoGet(url,
                           accept: null,
                           headers: GetApiHeaders());
            var serializer = new JavaScriptSerializer();
            return serializer.Deserialize<PingdomChecksResponse>(response).Checks;
        }

        public PingdomSummaryAverage GetSummaryAverage(int checkId, string probes = null, DateTime? from = null, DateTime? to = null)
        {
            var parameters = new Dictionary<string, string>();
            if (!string.IsNullOrEmpty(probes))
                parameters["probes"] = probes;
            if (from != null)
                parameters["from"] = ToUnixTimestamp(from.Value).ToString();
            if (to != null)
                parameters["to"] = ToUnixTimestamp(to.Value).ToString();

            var url = string.Format("{0}/api/2.0/summary.average/{1}", ApiUrl, checkId);
            var response = WebUtils.DoGet(url,
                           accept: null,
                           parameters:parameters,
                           headers: GetApiHeaders());

            var serializer = new JavaScriptSerializer();
            var result = serializer.Deserialize<PingdomSummaryResponse<PingdomSummaryAverageRT>>(response).Summary.ResponseTime;
            result.CheckID = checkId;
            return result;
        }

        public string GetSummaryHoursOfDay(int checkId, string probes = null, DateTime? from = null, DateTime? to = null)
        {
            var parameters = new Dictionary<string, string>();
            if (!string.IsNullOrEmpty(probes))
                parameters["probes"] = probes;
            if (from != null)
                parameters["from"] = ToUnixTimestamp(from.Value).ToString();
            if (to != null)
                parameters["to"] = ToUnixTimestamp(to.Value).ToString();

            var url = string.Format("{0}/api/2.0/summary.hoursofday/{1}", ApiUrl, checkId);
            var response = WebUtils.DoGet(url,
                           accept: null,
                           parameters: parameters,
                           headers: GetApiHeaders());

            return response;
        }

        /// <summary>
        /// For a given interval in time, return a list of sub intervals with the given resolution. Useful for generating graphs. A sub interval may be a week, a day or an hour depending on the choosen resolution
        /// </summary>
        /// <param name="checkId"></param>
        /// <param name="probes"></param>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="resolution">hour, day, week</param>
        /// <returns></returns>
        public PingdomSummaryPerformance GetSummaryPerformance(int checkId, string probes = null, DateTime? from = null, DateTime? to = null, string resolution = "hour")
        {
            var parameters = new Dictionary<string, string>();
            if (!string.IsNullOrEmpty(resolution))
                parameters["resolution"] = resolution;
            if (!string.IsNullOrEmpty(probes))
                parameters["probes"] = probes;
            if (from != null)
                parameters["from"] = ToUnixTimestamp(from.Value).ToString();
            if (to != null)
                parameters["to"] = ToUnixTimestamp(to.Value).ToString();

            var url = string.Format("{0}/api/2.0/summary.performance/{1}", ApiUrl, checkId);
            var response = WebUtils.DoGet(url,
                           accept: null,
                           parameters: parameters,
                           headers: GetApiHeaders());

            var serializer = new JavaScriptSerializer();
            var result = serializer.Deserialize<PingdomSummaryResponse<PingdomSummaryPerformance>>(response).Summary;
            result.CheckID = checkId;
            return result; 
        }

        public List<PingdomProbe> GetProbes(string countryiso = null)
        {
            var url = string.Format("{0}{1}", ApiUrl, "/api/2.0/probes");
            var response = WebUtils.DoGet(url,
                           accept: null,
                           headers: GetApiHeaders());
            var serializer = new JavaScriptSerializer();
            var result = serializer.Deserialize<PingdomProbesResponse>(response).Probes;
            if (!string.IsNullOrEmpty(countryiso))
                result = result.Where(c => c.CountryIso.Equals(countryiso, StringComparison.InvariantCultureIgnoreCase)).ToList();
            return result;
        }
    }
}
